var EventProxy = require('eventproxy');
var entity = require('../entity');
var logger = require('../service/Logger');
var imageHander = require('../service/imageHandler');
var redisManager = require('./redisManager');
var CardProxy = require('./card');
var Card = entity.Card;
var User = entity.User;
var Relation = entity.Relation;

exports.getUserById = function(id, callback){
    User.findOne({_id: id}).populate('card').exec(function(err, user){
        callback(err, user);
    });
}

exports.getUserByOpenId = function(openid, callback){
    User.findOne({openid: openid}).exec(function(err, user){
        callback(err, user);
    })
}

exports.findByIdArray = function(idArr, callback){
    User.find({_id: {$in: idArr}}, 'name headimg card').populate('card').exec(function(err, users){
        callback(err, users);
    })
}

exports.getFriends = function(userid, callback){
    Relation.findRelsByUserone(userid, function(err, rels){
        if(err) logger.error(err.message)
        var ep = new EventProxy();
        ep.after('friends', function(flist){
            callback(err, flist);
        })
        for(var i= 0, len=rels.length; i<len; i++){
            (function(id){
                redisManager.getUserById(id, function(err, user){
                    emit('friends', {
                        id: user.id,
                        name: user.name,
                        tag: user.tag
                    })
                })
            })(rels[i].usertwo)
        }
    })
}

exports.setDefaultCard = function(userid, card, callback){
    User.findOne({_id: userid}).exec(function(err, user){
        if(err) callback(err);
        user.card = card._id;
        /*User.update({_id: userid}, {$set: {card: card._id}}, {}, function(){
            callback();
        })*/
        user.save(function(err, user){
            callback(err, user)
        });
    })
}

exports.newAndSave = function (name, gender, city, province, country, openid, headimg, callback) {
    var ep = new EventProxy();
    ep.bind('error', function(err){
        ep.unbind();
        callback(err);
    })
    //TODO: RangeError: Maximum call stack size exceeded] 嫌疑！！！
    ep.all('saveUser', 'saveCard', function(user, card){
        Card.findOne({_id: card._id}).exec(function(err, card){
            if(err) callback(err);
            User.findOne({_id: user._id}).exec(function(err, user){
                if(err) callback(err);
                user.card = card._id;
                user.save(callback);
            })
        })
    })
    var user = new User();
    user.name = name;
    user.openid = openid;
    user.gender = gender;
    user.headimg = headimg;
    user.city = city;
    user.province = province;
    user.country = country;
    user.isBlock = false;
    user.save(function(err, data){
        // save header logo to mongo
        //TODO: 头像怀疑引起 RangeError: Maximum call stack size exceeded
        /*imageHander.handleAndSave(headimg, {
            size: 64,
            quality: 80,
            name: data._id+'.jpg'
        }, function(err, imgdata){
            if(err) return logger.error(err);
            logger.debug('save ['+imgdata.filename+'] headlogo success~');
        })*/
        // put into redis cache
        redisManager.putUserIntoCache(data, function(err, data){
            if(err) return logger.error(err);
            logger.debug('put ['+user.name+'] into cache~');
        });
        if(err){
            ep.emit('error', err);
        }else{
            ep.emit('saveUser', data);
        }
    });
    // create default card
    CardProxy.newAndSave(user, {}, function(err, data){
        if(err){
            ep.emit('error', err);
        }else{
            logger.debug('created ['+user.name+'] card~');
            ep.emit('saveCard', data);
        }
    })

}

exports.getAllUsers = function(callback){
    User.find().exec(function(err, users){
        callback(err, users);
    })
}

exports.increaseScore = function(targetUser, score, callback){
    User.findOne({_id: targetUser.id}).exec(function(err, user){
        if(err) return callback(err);
        user.score = score;
        user.save(function(err, user){
            if(err) return logger.error('User ['+user._id+'] add score '+score+' failed...');
            logger.debug('User ['+user._id+'] add score '+score);
            callback(err, user);
        })
    })
}

exports.setPrivacy4User = function(id, flag, colume, callback){
    User.findOne({_id: id}).exec(function(err, user){
        if(err) return callback(err);
        var permission = user.permission;
        switch (colume){
            case 'mobile':
                permission.showMobile = flag;
                break;
            case 'email':
                permission.showEmail = flag;
                break;
            case 'company':
                permission.showCompany = flag;
                break;
            case 'position':
                permission.showPosition = flag;
                break;
            case 'business':
                permission.showBusiness = flag;
                break;
            case 'product':
                permission.showPosition = flag;
                break;
        }
        User.update({_id: user._id}, {$set: {permission: permission}}, {}, function(err, data){
            callback(err, data)
        });
    })
}

exports.removeFaction = function(userid, factionid, callback){
    this.getUserById(userid, function(err, user){
        var factions = [];
        for(var i in user.factions){
            var tmp = user.factions[i];
            if(tmp && tmp.id && tmp.id !== factionid){
                factions.push(tmp);
                break;
            }
        }
        User.update({_id: user._id}, {$set: {factions: factions}}, {}, function(err, data){
            callback(err, data);
        })
    })
}